/* lfsmkdir.c  -  lfsmkdir */

#include <xinu.h>
#include <string.h>

/*------------------------------------------------------------------------
 * lfsmkdir  --  create a directory-type file on disk
 *------------------------------------------------------------------------
 */
struct	lflcblk	*lfdptr;		/* ptr to open file table entry	*/
struct	lflcblk	*lfdptr_ret;	/* return value of open file tab*/

int32 rec_mkdir	(
	char	*filename,
	struct 	ldentry	*lf_dirptr
	)
{
	char	*from, *to;			/* ptrs used during copy		*/
	char	*nam, *cmp;			/* ptrs used during comparison	*/
	char	*dname, *fname;		/* dir and file name in recursion	*/
	char	*pname;				/* file name used in recursion	*/
	int32	i, j, k;			/* general loop index			*/
	int32	pos;				/* where to add new dir entry	*/
	char	path[2][LF_NAME_LEN];	/* path names	*/
	struct	ldentry	*ldptr;		/* ptr to dir entry for opening file*/
	struct	ldentry *ldpaptr;	/* ptr to dir entry used in search	*/
	bool8	found;				/* was the name found?			*/
	uint32	pathnum;			/* record # dirs along the path	*/
	int32	retval;				/* value returned from function	*/
	
	/* parse the file name into directory along the path */
	from = filename;
	j = k = 0;
	for(i=1; from[i] != NULLCH; i++) {
		if(from[i] != '/') {
			if (j < 2) {
				path[j][k] = from[i];
			}
			k ++;
		}
		else {
			if (j < 2) {
				path[j][k] = NULLCH;
				j ++;
			}
			k = 0;
		}
	}
	if (j < 2) {
		path[j][k] = NULLCH;
	}
	
	pathnum = j;
	//kprintf("pathnum = %d\r\n", pathnum);
	//kprintf("path[0] = %s\r\n", path[0]);
	//kprintf("path[1] = %s\r\n", path[1]);
	dname = path[0];
	fname = path[1];
	
	//kprintf("\r\nLoad dir %s into memory\r\n", dname);
	/* Initialize the local file pseudo-device */
	lfdptr->lfdirptr = lf_dirptr;	/* point to dir's directory entry */
	//kprintf("(lfdptr->lfdirptr)->ld_size = %d\r\n", (lfdptr->lfdirptr)->ld_size);
	//kprintf("(lfdptr->lfdirptr)->ld_ilist = %d\r\n", (lfdptr->lfdirptr)->ld_ilist);
	//kprintf("(lfdptr->lfdirptr)->ld_name = %s\r\n", (lfdptr->lfdirptr)->ld_name);
	/* File starts at position 0 */
	lfdptr->lfpos     = 0;
	to = lfdptr->lfname;
	from = dname;
	while ( (*to++ = *from++) != NULLCH ) {
		;
	}
	/* Neither index block nor data block are initially valid	*/
	lfdptr->lfinum    = LF_INULL;
	lfdptr->lfdnum    = LF_DNULL;
	/* Initialize byte pointer to address beyond the end of the	*/
	/*	buffer (i.e., invalid pointer triggers setup)		*/
	lfdptr->lfbyte = &lfdptr->lfdblock[LF_BLKSIZ];
	lfdptr->lfibdirty = FALSE;
	lfdptr->lfdbdirty = FALSE;
	/* load directory /a into memory			*/
	signal(Lf_data.lf_mutex);
	/* Search /a directory to see if b exists 	*/
	//kprintf("search %s to see if %s exists\r\n", dname, fname);
	found = FALSE;
	ldpaptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
	for (i=0; i<((lfdptr->lfdirptr)->ld_size)/sizeof(struct ldentry); i++) {
		seek(lfdptr->lfdev, i*sizeof(struct ldentry));
		read(lfdptr->lfdev, (char *)ldpaptr, sizeof(struct ldentry));
		nam = fname;
		cmp = ldpaptr->ld_name;
		//kprintf("ldpaptr->ld_name = %s\r\n", ldpaptr->ld_name);
		while(*nam != NULLCH) {
			if (*nam != *cmp) {
				break;
			}
			nam++;
			cmp++;
		}
		if ( (*nam==NULLCH) && (*cmp==NULLCH) ) { /* name found	*/
			found = TRUE;
			ldptr = ldpaptr;
			break;
		}
	}
	pos = i;
	/* Case #1 - file b is not in directory a		*/
	if (! found) {
		//kprintf("Case #1 - file %s is not in directory %s\r\n", fname, dname);
		/* only one dir along the path, e.g. /a/b done		*/
		if (pathnum == 1) {
			//kprintf("only /%s/%s, no more path\r\n", fname, dname);
			/* Take steps to create b */
			//kprintf("Create ldptr for dir-type file %s\r\n", fname);
			ldptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
			ldptr->ld_size = 0;
			ldptr->ld_type = LF_TYPE_DIR;
			from = fname;
			to = ldptr->ld_name;
			while ( (*to++ = *from++) != NULLCH ) {
				;
			}
			ldptr->ld_ilist = LF_INULL;
			/* update b's dir entry in a				*/
			//kprintf("Update %s's dir entry in %s\r\n", fname, dname);
			signal(Lf_data.lf_mutex);
			seek(lfdptr->lfdev, pos*sizeof(struct ldentry));
			retval = write(lfdptr->lfdev, (char *)ldptr, sizeof(struct ldentry));
			//kprintf("write %d bytes\r\n", retval);
			//kprintf("ldptr->ld_name = %s\r\n", ldptr->ld_name);
			//kprintf("ldptr->ld_ilist = %d\r\n", ldptr->ld_ilist);
			//kprintf("ldptr->ld_size = %d\r\n", ldptr->ld_size);
			//kprintf("(lfdptr->lfdirptr)->ld_size = %d\r\n", (lfdptr->lfdirptr)->ld_size);
			//kprintf("(lfdptr->lfdirptr)->ld_ilist = %d\r\n", (lfdptr->lfdirptr)->ld_ilist);
			//kprintf("(lfdptr->lfdirptr)->ld_name = %s\r\n", (lfdptr->lfdirptr)->ld_name);
			ldpaptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
			seek(lfdptr->lfdev, 0);
			read(lfdptr->lfdev, (char *)ldpaptr, sizeof(struct ldentry));
			//kprintf("ldpaptr->ld_name = %s\r\n", ldpaptr->ld_name);
			//kprintf("ldpaptr->ld_ilist = %d\r\n", ldpaptr->ld_ilist);
			//kprintf("ldpaptr->ld_size = %d\r\n", ldpaptr->ld_size);
			freemem((char *)ldpaptr, sizeof(struct ldentry));
			wait(Lf_data.lf_mutex);
			/* Update the local file pseudo-device */
			//kprintf("Update local file pseudo-device\r\n");
			lfdptr_ret->lfstate = LF_USED;
			lfdptr_ret->lfdirptr = ldptr;	/* point to directory entry	*/
			/* File starts at position 0 */
			lfdptr_ret->lfpos     = 0;
			to = lfdptr_ret->lfname;
			from = fname;
			while ( (*to++ = *from++) != NULLCH ) {
				;
			}
			/* Neither index block nor data block are initially valid	*/
			lfdptr_ret->lfinum    = LF_INULL;
			lfdptr_ret->lfdnum    = LF_DNULL;
			/* Initialize byte pointer to address beyond the end of the	*/
			/*	buffer (i.e., invalid pointer triggers setup)		*/
			lfdptr_ret->lfbyte = &lfdptr->lfdblock[LF_BLKSIZ];
			lfdptr_ret->lfibdirty = FALSE;
			lfdptr_ret->lfdbdirty = FALSE;
			signal(Lf_data.lf_mutex);
			//kprintf("rec_mkdir Done\r\n");
			return lfdptr->lfdev;
		}
		/* more than 1 dir along the path, e.g. /a/b/c/d...	*/
		else if (pathnum > 1) {
			kprintf("more dires after /%s/%s\r\n", dname, fname);
			signal(Lf_data.lf_mutex);
			kprintf("No such directory %s exists\r\n", fname);
			return SYSERR;
		}
	}
	/* Case #2 - file b is in directory a		*/
	else {
		//kprintf("Case #2 - file %s is in directory %s\r\n", fname, dname);
		/* only one dir along the path, e.g. /a/b done		*/
		if (pathnum == 1) {
			//kprintf("only /%s/%s, no more path\r\n", fname, dname);
			if (ldpaptr->ld_type == LF_TYPE_DIR) {
				signal(Lf_data.lf_mutex);
				kprintf("Direcotry %s already exists\r\n", fname);
				return SYSERR;
			}
			if (ldpaptr->ld_type == LF_TYPE_FILE) {
				signal(Lf_data.lf_mutex);
				kprintf("File named %s already exists\r\n", fname);
				return SYSERR;
			}
		}
		/* more than 1 dir along the path, e.g. /a/b/c/d...	*/
		else if (pathnum > 1) {
			//kprintf("more dires after /%s/%s\r\n", fname, dname);
			pname = strchr(filename+1, '/');
			//kprintf("recursively open %s begins\r\n", pname);
			retval = rec_mkdir(pname, ldptr);
			if (retval == SYSERR ) {
				kprintf("lfsmkdir fails\r\n\r\n");
				return SYSERR;
			}
			else {
				/* update b's dir entry in a				*/
				//kprintf("Update %s's dir entry in %s\r\n", fname, dname);
				lfdptr->lfdirptr = lf_dirptr;
				lfdptr->lfpos	= pos*sizeof(struct ldentry);
				lfdptr->lfpos     = 0;
				to = lfdptr->lfname;
				from = fname;
				while ( (*to++ = *from++) != NULLCH ) {
					;
				}
				lfdptr->lfinum    = LF_INULL;
				lfdptr->lfdnum    = LF_DNULL;
				lfdptr->lfbyte = &lfdptr->lfdblock[LF_BLKSIZ];
				lfdptr->lfibdirty = FALSE;
				lfdptr->lfdbdirty = FALSE;
				signal(Lf_data.lf_mutex);
				write(lfdptr->lfdev, (char *)ldptr, sizeof(struct ldentry));
				seek(lfdptr->lfdev, 0);
				ldpaptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
				read(lfdptr->lfdev, (char *)ldpaptr, sizeof(struct ldentry));
				freemem((char *)ldpaptr, sizeof(struct ldentry));
				wait(Lf_data.lf_mutex);
				//kprintf("recursively open %s done\r\n", pname);
				return retval;
			}
		}
	}
	return SYSERR;
}
 
devcall	lfsmkdir (
	 struct	dentry	*devptr,	/* entry in device switch table	*/
	 char	*name				/* name of file (path include) to open */
	)
{
	struct	lfdir	*dirptr;	/* ptr to in-memory sector 0	*/
	did32	lfnext;				/* minor number of an unused	*/
								/*    file pseudo-device		*/
	int32	retval;				/* value returned from function	*/
	char	*from,	*to;		/* ptrs used during copy		*/
	int32	i, j, k;			/* general loop index			*/
	char	finalfname[LF_NAME_LEN];/* final file name to open		*/
	char	path[2][LF_NAME_LEN]; 			/* path names	*/
	uint32	pathnum;			/* record # dirs along the path	*/
	char	*nam, *cmp;			/* ptrs used during comparison	*/
	struct	ldentry	*ldptr;		/* ptr to dir entry for opening file*/
	struct	ldentry *ldpaptr;	/* ptr to dir entry used in search	*/
	bool8	found;				/* was the name found?			*/
	int32	pos;				/* where to add new dir entry	*/
	
	/* parse the file name into directory along the path */
	from = name;
	j = k = 0;
	if (from[0] != '/') {
		kprintf("File name should start with '/'\r\n");
		return SYSERR;
	}
	for(i=1; from[i] != NULLCH; i++) {
		if(from[i] != '/') {
			if (j < 2) {
				path[j][k] = from[i];
			}
			finalfname[k++] = from[i];
		}
		else {
			if (j < 2) {
				path[j][k] = NULLCH;
				j ++;
			}
			finalfname[k] = NULLCH;
			k = 0;
		}
	}
	if (j < 2) {
		path[j][k] = NULLCH;
	}
	finalfname[k] = NULLCH; /* actual file name to open	*/
	pathnum = j;
	/* kprintf("finalfname = %s\r\n", finalfname);
	kprintf("pathnum = %d\r\n", pathnum);
	kprintf("path[0] = %s\r\n", path[0]);
	kprintf("path[1] = %s\r\n", path[1]); */
	
	/* Check length of name file (leaving space for NULLCH */
	from = finalfname;
	for (i=0; i< LF_NAME_LEN; i++) {
		if (*from++ == NULLCH) {
			break;
		}
	}
	if (i >= LF_NAME_LEN) {		/* name is too long */
		kprintf("Name is too long\r\n");
		return SYSERR;
	}
	
	/* If named file is already open, return SYSERR */
	lfnext = SYSERR;
	for (i=0; i<Nlfl; i++) {	/* search file pseudo-devices	*/
		lfdptr = &lfltab[i];
		if (lfdptr->lfstate == LF_FREE) {
			if (lfnext == SYSERR) {
				lfnext = i; /* record index */
			}
			continue;
		}
		/* Compare requested name to name of open file */
		nam = name;
		cmp = lfdptr->lftotname;
		while(*nam != NULLCH) {
			if (*nam != *cmp) {
				break;
			}
			nam++;
			cmp++;
			//kprintf("WTF\r\n");
		}
		/* See if comparison succeeded */
		if ( (*nam==NULLCH) && (*cmp == NULLCH) ) {
			kprintf("file is already open\r\n");
			return SYSERR;
		}
	}
	if (lfnext == SYSERR) {	/* no slave file devices are available	*/
		kprintf("No slave file devices are available\r\n");
		return SYSERR;
	}

	/* Obtain copy of Sector 0 if not already present in memory	*/
	dirptr = &Lf_data.lf_dir;
	wait(Lf_data.lf_mutex);
	if (! Lf_data.lf_dirpresent) {
	    retval = read(Lf_data.lf_dskdev,(char *)dirptr,LF_AREA_DIR);
	    if (retval == SYSERR ) {
		signal(Lf_data.lf_mutex);
		kprintf("Cannot not read Sector 0 into memory\r\n");
		return SYSERR;
	    }
	    //kprintf("Read sector 0 done!\r\n");
	    //kprintf("dirptr->lfd_dfree = %d\r\n", dirptr->lfd_dfree);
	    //kprintf("dirptr->lfd_ifree = %d\r\n", dirptr->lfd_ifree);
	    //kprintf("(dirptr->root_entry).ld_size = %d\r\n", (dirptr->root_entry).ld_size);
	    //kprintf("(dirptr->root_entry).ld_ilist = %d\r\n", (dirptr->root_entry).ld_ilist);
	    //kprintf("(dirptr->root_entry).ld_name = %s\r\n", (dirptr->root_entry).ld_name);
	    //Lf_data.lf_dirpresent = TRUE;
	}
	
	//kprintf("\r\nLoad root dir into memory\r\n");
	/* Initialize the local file pseudo-device */
	/* point to root directory entry*/
	lfdptr = &lfltab[lfnext];
	lfdptr_ret = (struct	lflcblk *)getmem(sizeof(struct	lflcblk));
	lfdptr->lfstate = LF_USED;
	lfdptr->lfdirptr = &(dirptr->root_entry);
	/* File starts at position 0 */
	lfdptr->lfpos     = 0;
	lfdptr->lfname[0] = '/';
	lfdptr->lfname[1] = NULLCH;
	/* Neither index block nor data block are initially valid	*/
	lfdptr->lfinum    = LF_INULL;
	lfdptr->lfdnum    = LF_DNULL;
	/* Initialize byte pointer to address beyond the end of the	*/
	/*	buffer (i.e., invalid pointer triggers setup)		*/
	lfdptr->lfbyte = &lfdptr->lfdblock[LF_BLKSIZ];
	lfdptr->lfibdirty = FALSE;
	lfdptr->lfdbdirty = FALSE;
	/* Load the root directory into memory, "open" root file 	*/	
	signal(Lf_data.lf_mutex);
	/* Search root directory to see if file exists */
	//kprintf("search root to see if %s exists\r\n", path[0]);
	found = FALSE;
	ldpaptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
	for (i=0; i<((lfdptr->lfdirptr)->ld_size)/sizeof(struct ldentry); i++) {
		seek(lfdptr->lfdev, i*sizeof(struct ldentry));
		read(lfdptr->lfdev, (char *)ldpaptr, sizeof(struct ldentry));
		nam = path[0];
		cmp = ldpaptr->ld_name;
		//kprintf("ldpaptr->ld_name = %s\r\n", ldpaptr->ld_name);
		while(*nam != NULLCH) {
			if (*nam != *cmp) {
				break;
			}
			nam++;
			cmp++;
		}
		if ( (*nam==NULLCH) && (*cmp==NULLCH) ) { /* name found	*/
			found = TRUE;
			ldptr = ldpaptr;
			break;
		}
	}
	pos = i;
	wait(Lf_data.lf_mutex);
	/* Case #1 - file is not in root directory	*/
	if (! found) {
		//kprintf("Case #1 - %s is not in root directory\r\n", path[0]);
		/* open file direcotry in root directory, e.g. /a		*/
		if (pathnum == 0) {
			//kprintf("only /%s, no more path\r\n", path[0]);
			/* Take steps to create new file and add to root directory	*/
			//kprintf("Create ldptr for dir-type file %s\r\n", path[0]);
			ldptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
			ldptr->ld_size = 0;
			ldptr->ld_type = LF_TYPE_DIR;
			from = finalfname;
			to = ldptr->ld_name;
			while ( (*to++ = *from++) != NULLCH ) {
				;
			}
			ldptr->ld_ilist = LF_INULL;
			/* update a's dir entry in root directory	*/
			//kprintf("Update %s's dir entry in root directory\r\n", path[0]);
			/* temporarily give up exclusive access to Sector 0	*/
			signal(Lf_data.lf_mutex);
			seek(lfdptr->lfdev, pos*sizeof(struct ldentry));
			write(lfdptr->lfdev, (char *)ldptr, sizeof(struct ldentry));
			//kprintf("Write ldptr->ld_name = %s\r\n", ldptr->ld_name);
			seek(lfdptr->lfdev, 0);
			ldpaptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
			read(lfdptr->lfdev, (char *)ldpaptr, sizeof(struct ldentry));
			freemem((char *)ldpaptr, sizeof(struct ldentry));
			//kprintf("ldpaptr->ld_name = %s\r\n", ldpaptr->ld_name);
			/* update root's dir entry in Sector 0		*/
			write(Lf_data.lf_dskdev,(char *)dirptr,LF_AREA_DIR);
			/* obtain exclusive access to Sector 0	*/
			wait(Lf_data.lf_mutex);
			/* Update the local file pseudo-device */
			//kprintf("Update local file pseudo-device\r\n");
			lfdptr->lfdirptr = ldptr;	/* point to directory entry	*/
			/* File starts at position 0 */
			lfdptr->lfpos     = 0;
			to = lfdptr->lfname;
			from = finalfname;
			while ( (*to++ = *from++) != NULLCH ) {
				;
			}
			to = lfdptr->lftotname;
			from = name;
			while ( (*to++ = *from++) != NULLCH ) {
					;
			}
			/* Neither index block nor data block are initially valid	*/
			lfdptr->lfinum    = LF_INULL;
			lfdptr->lfdnum    = LF_DNULL;
			/* Initialize byte pointer to address beyond the end of the	*/
			/*	buffer (i.e., invalid pointer triggers setup)		*/
			lfdptr->lfbyte = &lfdptr->lfdblock[LF_BLKSIZ];
			lfdptr->lfibdirty = FALSE;
			lfdptr->lfdbdirty = FALSE;
			//kprintf("update the local file pseudo-device done\r\n");
			signal(Lf_data.lf_mutex);
			//kprintf("lfsmkdir Done\r\n");
			//kprintf("========================================\r\n\r\n");
			return lfdptr->lfdev;
		}
		else if (pathnum > 1) {
			kprintf("more dires after /%s\r\n", path[0]);
			signal(Lf_data.lf_mutex);
			kprintf("No such directory %s exists\r\n", path[0]);
			return SYSERR;
		}
	}
	/* Case #2 - file is in root directory		*/
	else {
		//kprintf("Case #2 - %s is in root directory\r\n", path[0]);
		/* open file direcotry in root directory, e.g. /a		*/
		if (pathnum == 0) {
			//kprintf("only /%s, no more path\r\n", path[0]);
			if (ldpaptr->ld_type == LF_TYPE_DIR) {
				signal(Lf_data.lf_mutex);
				kprintf("Direcotry %s already exists\r\n", path[0]);
				return SYSERR;
			}
			if (ldpaptr->ld_type == LF_TYPE_FILE) {
				signal(Lf_data.lf_mutex);
				kprintf("File named %s already exists\r\n", path[0]);
				return SYSERR;
			}
		}
		else if (pathnum > 0) {
			//kprintf("more dires after /%s\r\n", path[0]);
			if (ldpaptr->ld_type == LF_TYPE_FILE) {
				signal(Lf_data.lf_mutex);
				kprintf("No such direcotry %s exists\r\n", path[0]);
				return SYSERR;
			}
			//kprintf("recursively mkdir %s begins\r\n", name);
			retval = rec_mkdir(name, ldptr);
			if (retval == SYSERR ) {
				kprintf("lfsmkdir fails\r\n\r\n");
				return SYSERR;
			}
			else {
				//kprintf("recursively mkdir %s done\r\n", name);
				/* update a's dir entry in root directory	*/
				/* temporarily give up exclusive access to Sector 0	*/
				//kprintf("Update %s's dir entry in root direcotry\r\n", path[0]);
				lfdptr->lfdirptr = &(dirptr->root_entry);
				lfdptr->lfpos	= pos*sizeof(struct ldentry);
				lfdptr->lfname[0] = '/';
				lfdptr->lfname[1] = NULLCH;
				lfdptr->lfinum    = LF_INULL;
				lfdptr->lfdnum    = LF_DNULL;
				lfdptr->lfbyte = &lfdptr->lfdblock[LF_BLKSIZ];
				signal(Lf_data.lf_mutex);
				write(lfdptr->lfdev, (char *)ldptr, sizeof(struct ldentry));
				seek(lfdptr->lfdev, 0);
				/*kprintf("ldptr->ld_name = %s\r\n", ldptr->ld_name);
				kprintf("ldptr->ld_ilist = %d\r\n", ldptr->ld_ilist);
				kprintf("ldptr->ld_size = %d\r\n", ldptr->ld_size);
				kprintf("(lfdptr->lfdirptr)->ld_size = %d\r\n", (lfdptr->lfdirptr)->ld_size);
				kprintf("(lfdptr->lfdirptr)->ld_ilist = %d\r\n", (lfdptr->lfdirptr)->ld_ilist);
				kprintf("(lfdptr->lfdirptr)->ld_name = %s\r\n", (lfdptr->lfdirptr)->ld_name); */
				ldpaptr = (struct	ldentry	*)getmem(sizeof(struct ldentry));
				read(lfdptr->lfdev, (char *)ldpaptr, sizeof(struct ldentry));
				/* kprintf("ldpaptr->ld_name = %s\r\n", ldpaptr->ld_name);
				kprintf("ldpaptr->ld_ilist = %d\r\n", ldpaptr->ld_ilist);
				kprintf("ldpaptr->ld_size = %d\r\n", ldpaptr->ld_size);
				freemem((char *)ldpaptr, sizeof(struct ldentry)); */
				/* update root's dir entry in Sector 0		*/
				write(Lf_data.lf_dskdev,(char *)dirptr,LF_AREA_DIR);
				wait(Lf_data.lf_mutex);
				//kprintf("lfsmkdir Done\r\n");
				//kprintf("========================================\r\n\r\n");
				signal(Lf_data.lf_mutex);
				lfdptr->lfdirptr = lfdptr_ret->lfdirptr;
				lfdptr->lfstate = lfdptr_ret->lfstate;
				lfdptr->lfpos = lfdptr_ret->lfpos;
				to = lfdptr->lfname;
				from = lfdptr_ret->lfname;
				while ( (*to++ = *from++) != NULLCH ) {
					;
				}
				to = lfdptr->lftotname;
				from = name;
				while ( (*to++ = *from++) != NULLCH ) {
					;
				}
				lfdptr->lfinum = lfdptr_ret->lfinum;
				lfdptr->lfdnum = lfdptr_ret->lfdnum;
				lfdptr->lfbyte = lfdptr_ret->lfbyte;
				lfdptr->lfibdirty = lfdptr_ret->lfibdirty;
				lfdptr->lfdbdirty = lfdptr_ret->lfdbdirty;
				return retval;
			}
		}
	}
	return SYSERR;
}
